/**************************************************************************************************

	NSurvey - The web survey and form engine
	Copyright (c) 2004, Thomas Zumbrunn. (http://www.nsurvey.org)

	Dotnetnuke PA module 
	Copyright (c) 2004, Oliver Hine (oliver.hine@gmail.com)

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


************************************************************************************************/
using DotNetNuke;
using System;
using System.Collections.Specialized;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.VisualBasic;
using Votations.NSurvey.DataAccess;
using Votations.NSurvey.Data;
using Votations.NSurvey.WebAdmin.UserControls;
using Votations.NSurvey.Enums;
using Votations.NSurvey.Security;
using Votations.NSurvey.Helpers;

namespace Votations.NSurvey.WebAdmin
{
	public class VoterReport : PageBase
	{
		protected System.Web.UI.WebControls.Label MessageLabel;
		protected System.Web.UI.WebControls.Label VoterUIDLabel;
		protected System.Web.UI.WebControls.Label IPAddressLabel;
		protected System.Web.UI.WebControls.Label VoteDateLabel;
		protected System.Web.UI.WebControls.Literal VoterUserNameLabel;
		protected System.Web.UI.WebControls.Label VoterUserName;
		protected System.Web.UI.WebControls.Label TimeToTakeSurveyLabel;
		protected System.Web.UI.WebControls.DataGrid QuestionsDataGrid;
		protected System.Web.UI.WebControls.Label VoterEmail;
		protected System.Web.UI.WebControls.Literal VoterInformationTitle;
		protected System.Web.UI.WebControls.Literal VoterDBIDLabel;
		protected System.Web.UI.WebControls.Literal VoterEmailLabel;
		protected System.Web.UI.WebControls.Literal VoterIPAddressLabel;
		protected System.Web.UI.WebControls.Literal VoteRecordedLabel;
		protected System.Web.UI.WebControls.Literal TimeToTakeLabel;
		protected System.Web.UI.WebControls.Literal SurveyAnswersTitle;
		protected System.Web.UI.WebControls.PlaceHolder AddInVoterDataPlaceHolder;
		protected System.Web.UI.WebControls.LinkButton EditAnswersLinkButton;
		protected System.Web.UI.WebControls.Label VoterScoreTotalLabel;
		protected HeaderControl Header;

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.EditAnswersLinkButton.Click += new System.EventHandler(this.EditAnswersLinkButton_Click);
			this.QuestionsDataGrid.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.BindQuestions);
			this.Load += new System.EventHandler(this.Page_Load);
		}
		#endregion

		private void Page_Load(object sender, System.EventArgs e)
		{
			try
			{
				SetupSecurity();
				LocalizePage();

				if (Information.IsNumeric(Request["voterid"]))
				{
					_voterId =  int.Parse(Request["voterid"]);
				}
				else
				{
					throw new FormatException("Invalid voter id!");
				}

				if (!Page.IsPostBack)
				{
					Header.SurveyId = SurveyId;
					BindData();
				}
			}
			catch( Exception exc)
			{
				DotNetNuke.Services.Exceptions.Exceptions.ProcessModuleLoadException(this,exc);
			}
		}

		private void SetupSecurity()
		{
			CheckRight(NSurveyRights.AccessFieldEntries, true);
			EditAnswersLinkButton.Visible = CheckRight(NSurveyRights.EditVoterEntries, false);
		}

		private void LocalizePage()
		{
			VoterInformationTitle.Text = GetPageResource("VoterInformationTitle");
			VoterDBIDLabel.Text = GetPageResource("VoterDBIDLabel");
			VoterEmailLabel.Text = GetPageResource("VoterEmailLabel");
			VoterUserNameLabel.Text = GetPageResource("VoterUserNameLabel");
			VoterIPAddressLabel.Text = GetPageResource("VoterIPAddressLabel");
			VoteRecordedLabel.Text = GetPageResource("VoteRecordedLabel");
			TimeToTakeLabel.Text = GetPageResource("TimeToTakeLabel");
			SurveyAnswersTitle.Text = GetPageResource("SurveyAnswersTitle");
			EditAnswersLinkButton.Text = GetPageResource("EditAnswersLinkButton");
		}

		/// <summary>
		/// Get the current DB stats and fill 
		/// the label with them
		/// </summary>
		private void BindData()
		{
			isScored = new Surveys().IsSurveyScored(SurveyId);

			TimeSpan timeTaken;
			_voterAnswers = new Voters().GetVoterAnswers(_voterId);

			if (!_voterAnswers.Voters[0].IsVoteDateNull() && !_voterAnswers.Voters[0].IsStartDateNull())
			{
				timeTaken = _voterAnswers.Voters[0].VoteDate - _voterAnswers.Voters[0].StartDate;
			}
			else
			{
				timeTaken = new TimeSpan(0);
			}

			VoterUIDLabel.Text = _voterId.ToString();
			IPAddressLabel.Text = _voterAnswers.Voters[0].IPSource;
			VoteDateLabel.Text = _voterAnswers.Voters[0].VoteDate.ToString();
			VoterEmail.Text = _voterAnswers.Voters[0].IsEmailNull() ? GetPageResource("AnonymousVoteInfo") : _voterAnswers.Voters[0].Email;
			VoterUserName.Text = _voterAnswers.Voters[0].IsContextUserNameNull() ?  GetPageResource("ContextUserNameDisabled") : _voterAnswers.Voters[0].ContextUserName;
			TimeToTakeSurveyLabel.Text = string.Format("{0} {1}, {2} secs.", timeTaken.Minutes.ToString(), GetPageResource("MinutesInfo"), timeTaken.Seconds.ToString());

			WebSecurityAddInCollection securityAddIns = WebSecurityAddInFactory.CreateWebSecurityAddInCollection(new SecurityAddIns().GetWebSecurityAddIns(SurveyId), ViewState);
			NameValueCollection addInVoterData;
			for (int i=0;i<securityAddIns.Count;i++)
			{
				addInVoterData = securityAddIns[i].GetAddInVoterData(_voterId);
				if (addInVoterData != null)
				{
					// Creates a new addin voter details page
					SecurityAddInVoterReportControl addInVoterControl = 
						(SecurityAddInVoterReportControl)LoadControl("UserControls/SecurityAddInVoterReportControl.ascx");

					addInVoterControl.AddInDescription = securityAddIns[i].Description;
					addInVoterControl.AddInVoterData = addInVoterData;
					AddInVoterDataPlaceHolder.Controls.Add(addInVoterControl);
				}
			}

			_questionData = new Questions().GetQuestionHierarchy(SurveyId);
			QuestionsDataGrid.DataSource = GetParentQuestions();
			QuestionsDataGrid.DataKeyField = "QuestionId";
			QuestionsDataGrid.DataBind();
			if (isScored)
			{
				VoterScoreTotalLabel.Text = GetPageResource("VoterScoreTotalLabel") + _totalScore.ToString();
			}
		}

		private DataView GetParentQuestions()
		{
			string filter = string.Format("Isnull(ParentQuestionID,0) = 0",	
				(int)QuestionTypeMode.Answerable);
			return new DataView(_questionData.Questions,filter,"DisplayOrder", DataViewRowState.CurrentRows);
		}

		private void BindQuestions(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
			if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
			{
				int questionId = int.Parse(QuestionsDataGrid.DataKeys[e.Item.ItemIndex].ToString());
				
				// Check if the question has childs
				string filter = string.Format("ParentQuestionID = {0}", questionId); 
				DataView childQuestions = 
					new DataView(_questionData.Questions,filter,"DisplayOrder", DataViewRowState.CurrentRows);
				if (childQuestions.Count == 0)
				{
					BindAnswerDataGrid(questionId, 
						(DataGrid)e.Item.Cells[0].FindControl("QuestionAnswersDataGrid"));
				
					Label scoreTotalLabel = (Label)e.Item.Cells[0].FindControl("QuestionScoreLabel");
					if (isScored)
					{
						scoreTotalLabel.Text = string.Format("<br>" +GetPageResource("QuestionScoreLabel")+ _questionScore);
					}
					_totalScore += _questionScore;
					_questionScore = 0;
				}
				else
				{
					BindMatrix(childQuestions,
						(PlaceHolder)e.Item.Cells[0].FindControl("MatrixPlaceHolder"));
				}
			}

		}

		private void BindMatrix(DataView childQuestions, PlaceHolder container)
		{
			Table selectionTable = new Table();
			TableRow	selectionRow = new TableRow(),
				matrixHeaderRow = new TableRow();							
			TableCell	selectionCell;	// Selection cell for the answer item
			bool generateHeader = true;	// Header generation in progress
			System.Web.UI.WebControls.Image spotImage = new System.Web.UI.WebControls.Image();

			selectionTable.CssClass = "innerText";
		
			// Creates header's first empty cell 
			TableCell answerHeaderCell = new TableCell();
			matrixHeaderRow.Cells.Add(answerHeaderCell);

			// Get all answer items available for this
			// question
			foreach (DataRowView questionRow in childQuestions)
			{
				selectionRow = new TableRow();
				TableCell questionCell = new TableCell();
				questionCell.VerticalAlign = VerticalAlign.Top;
				questionCell.Text = new PipeManager().PipeValuesInText(
					int.Parse(questionRow["QuestionId"].ToString()),questionRow["QuestionText"].ToString(), _voterAnswers.VotersAnswers);

				selectionRow.Cells.Add(questionCell);
				
				// Parse the child question's answers
				AnswerData questionAnswers = new Answers().GetAnswers(int.Parse(questionRow["QuestionId"].ToString()));
				foreach (AnswerData.AnswersRow answer in questionAnswers.Answers)
				{
					// New spot image
					spotImage = new System.Web.UI.WebControls.Image();

					// Creates a new answer text in the matrix header
					if (generateHeader)
					{
						answerHeaderCell = new TableCell();
						answerHeaderCell.VerticalAlign = VerticalAlign.Top;
						answerHeaderCell.HorizontalAlign = HorizontalAlign.Center;
						answerHeaderCell.Text = 
							new PipeManager().PipeValuesInText(answer.QuestionId, answer.AnswerText, _voterAnswers.VotersAnswers);
						matrixHeaderRow.Cells.Add(answerHeaderCell);
					}

					// Add a new selection to the matrix's child question
					selectionCell = new TableCell();
					selectionCell.VerticalAlign = VerticalAlign.Top;
					selectionCell.HorizontalAlign = HorizontalAlign.Center;
					
					// Check if the voter has answered this answer
					VoterAnswersData.VotersAnswersRow voterAnswer = _voterAnswers.VotersAnswers.FindByVoterIdAnswerId(_voterId, answer.AnswerId);
					if (voterAnswer != null)
					{
						// Check answer type
						if ((((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.Field) > 0) || 
							(((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.Custom) > 0) ||
							(((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.DataSource) > 0))
						{
							selectionCell.Text = FormatVoterAnswer(null, voterAnswer.AnswerText,true);
						}
						else
						{
							spotImage.ImageUrl = "images/spot_on.gif";
							selectionCell.Controls.Add(spotImage);
						}
					}
					else
					{
						// Check answer type
						if ((((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.Field) > 0)  || 
							(((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.Custom) > 0) ||
							(((AnswerTypeMode)answer.TypeMode & AnswerTypeMode.DataSource) > 0))
						{
							selectionCell.Text = FormatVoterAnswer(null,null,false);
						}
						else
						{
							spotImage.ImageUrl = "images/spot_off.gif";
							selectionCell.Controls.Add(spotImage);
						}
					}

					selectionRow.Cells.Add(selectionCell);
				}
				
				// Generates the answer text header
				if (generateHeader)
				{
					selectionTable.Rows.Add(matrixHeaderRow);
					generateHeader = false;					
				}
				
				selectionTable.Rows.Add(selectionRow);
			}


			selectionTable.Width = Unit.Percentage(100);

			container.Controls.Add(selectionTable);
		}

		private void BindAnswerDataGrid(int questionId, DataGrid answersDataGrid)
		{
			// Bind the answers of the question
			AnswerData questionAnswers = new Answers().GetAnswers(questionId);
			answersDataGrid.DataSource = questionAnswers;
			answersDataGrid.DataKeyField = "AnswerId";
			answersDataGrid.ItemDataBound += new DataGridItemEventHandler(BindAnswers);
			answersDataGrid.DataBind();
		}
		
		private void BindAnswers(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
			if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
			{
				int answerId = int.Parse(((DataGrid)sender).DataKeys[e.Item.ItemIndex].ToString());
				int typeMode = int.Parse(DataBinder.Eval(e.Item.DataItem,"typeMode").ToString());
				int score = DataBinder.Eval(e.Item.DataItem,"ScorePoint").ToString().Length > 0 ?
					int.Parse(DataBinder.Eval(e.Item.DataItem,"ScorePoint").ToString()) : 0;
				string answerText = Server.HtmlEncode(
					System.Text.RegularExpressions.Regex.Replace(new PipeManager().PipeValuesInText(
					int.Parse(DataBinder.Eval(e.Item.DataItem,"QuestionId").ToString()),
					DataBinder.Eval(e.Item.DataItem,"AnswerText").ToString(), _voterAnswers.VotersAnswers), 
					"<[^>]*>", " "));
				System.Web.UI.WebControls.Image spotImage = new System.Web.UI.WebControls.Image();
				spotImage.ImageUrl = "images/spot_on.gif";
				
				// Check if the voter has answered this answer
				VoterAnswersData.VotersAnswersRow voterAnswer = _voterAnswers.VotersAnswers.FindByVoterIdAnswerId(_voterId, answerId);
				if (voterAnswer != null)
				{
					// Check answer type
					if (((((AnswerTypeMode)typeMode & AnswerTypeMode.Field) > 0) || 
						(((AnswerTypeMode)typeMode & AnswerTypeMode.Custom) > 0) ||
						(((AnswerTypeMode)typeMode & AnswerTypeMode.DataSource) > 0)) &&
						(((AnswerTypeMode)typeMode & AnswerTypeMode.Selection) == 0))
					{
						spotImage.ImageUrl = "images/spot_text.gif";
						e.Item.Cells[1].Text = FormatVoterAnswer(answerText, voterAnswer.AnswerText, true);
					}
					else if ((((AnswerTypeMode)typeMode - AnswerTypeMode.Other) == 0))
					{
						e.Item.Cells[1].Text = FormatVoterAnswer(answerText, voterAnswer.AnswerText,true);
						_questionScore += score;
					}
					else
					{
						e.Item.Cells[1].Text = string.Format("<b>{0}</b>", answerText);
						_questionScore += score;
					}
				}
				else
				{
					// Check answer type
					if (((((AnswerTypeMode)typeMode & AnswerTypeMode.Field) > 0) ||
						(((AnswerTypeMode)typeMode & AnswerTypeMode.Custom) > 0) ||
						(((AnswerTypeMode)typeMode & AnswerTypeMode.DataSource) > 0)) &&
						(((AnswerTypeMode)typeMode & AnswerTypeMode.Selection) == 0))
					{
						spotImage.ImageUrl = "images/spot_text.gif";
						e.Item.Cells[1].Text = FormatVoterAnswer(answerText, null, false);
					}
					else
					{
						spotImage.ImageUrl = "images/spot_off.gif";
					}
				}

				e.Item.Cells[0].Controls.Add(spotImage);
			}
		}

		string FormatVoterAnswer(string answer, string voterAnswer, bool selected)
		{
			if (voterAnswer == null)
			{
				if (answer == null ||  answer.Length == 0)
				{
					return GetPageResource("AnswerNotAnsweredMessage");
				}
				else
				{
					if (selected)
					{
						return string.Format("<B>{0}</B> :<br>{1}",answer, GetPageResource("AnswerNotAnsweredMessage"));
					}
					else
					{
						return string.Format("{0} :<br>{1}",answer, GetPageResource("AnswerNotAnsweredMessage"));
					}
				}
			}
			else
			{
				if (answer == null)
				{
					if (selected)
					{
						return string.Format("<b>{0}</b>", voterAnswer);
					}
					else
					{
						return  voterAnswer;
					}
				}
				else
				{
					if (selected)
					{
						return string.Format("<b>{0}</b> :<br>{1}",answer, voterAnswer);
					}
					else
					{
						return string.Format("{0} :<br>{1}",answer, voterAnswer);
					}
				}
			}
		}

		private void EditAnswersLinkButton_Click(object sender, System.EventArgs e)
		{
			UINavigator.NavigateToEditVoterReport(SurveyId, _voterId, MenuIndex);
		}

		int _voterId,
			_questionScore = 0,
			_totalScore = 0;
		bool isScored = false;
		protected VoterAnswersData _voterAnswers;
		QuestionData _questionData;

	}
}
